/**
* Copyright (C) 2018-2020
* All rights reserved, Designed By www.gzchengguo.cn
* 注意：
* 本软件为www.gzchengguo.cn开发研制，未经购买不得商用
* 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
* 一经发现盗用、分享等行为，将追究法律责任，后果自负
*/
package link.chengguo.orangemall.modules.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import link.chengguo.orangemall.api.BusinessException;
import link.chengguo.orangemall.api.OrangeException;
import link.chengguo.orangemall.common.service.impl.BaseServiceImpl;
import link.chengguo.orangemall.dozer.service.IGenerator;
import link.chengguo.orangemall.modules.product.domain.OrangeStoreProductAttr;
import link.chengguo.orangemall.modules.product.domain.OrangeStoreProductAttrValue;
import link.chengguo.orangemall.modules.product.service.OrangeStoreProductAttrResultService;
import link.chengguo.orangemall.modules.product.service.OrangeStoreProductAttrService;
import link.chengguo.orangemall.modules.product.service.OrangeStoreProductAttrValueService;
import link.chengguo.orangemall.modules.product.service.dto.AttrValueDto;
import link.chengguo.orangemall.modules.product.service.dto.FromatDetailDto;
import link.chengguo.orangemall.modules.product.service.dto.ProductFormatDto;
import link.chengguo.orangemall.modules.product.service.mapper.StoreProductAttrMapper;
import link.chengguo.orangemall.modules.product.service.mapper.StoreProductAttrValueMapper;
import link.chengguo.orangemall.modules.product.vo.OrangeStoreProductAttrQueryVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
* @author chengguo
* @date 2020-05-12
*/
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class OrangeStoreProductAttrServiceImpl extends BaseServiceImpl<StoreProductAttrMapper, OrangeStoreProductAttr> implements OrangeStoreProductAttrService {

    @Autowired
    private IGenerator generator;

    @Autowired
    private StoreProductAttrMapper orangeStoreProductAttrMapper;
    @Autowired
    private StoreProductAttrValueMapper orangeStoreProductAttrValueMapper;

    @Autowired
    private OrangeStoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private OrangeStoreProductAttrResultService storeProductAttrResultService;

    /**
     * 新增商品属性
     * @param items attr
     * @param attrs value
     * @param productId 商品id
     */
    @Override
    @Transactional
    public void insertOrangeStoreProductAttr(List<FromatDetailDto> items, List<Map<String,Object>> attrs,
                                         Long productId)
    {
        List<OrangeStoreProductAttr> attrGroup = new ArrayList<>();
        for (FromatDetailDto fromatDetailDto : items) {
            OrangeStoreProductAttr orangeStoreProductAttr = OrangeStoreProductAttr.builder()
                    .productId(productId)
                    .attrName(fromatDetailDto.getValue())
                    .attrValues(StrUtil.join(",",fromatDetailDto.getDetail()))
                    .build();

            attrGroup.add(orangeStoreProductAttr);
        }


        List<OrangeStoreProductAttrValue> valueGroup = new ArrayList<>();
        for (Map<String, Object> m : attrs) {
            ProductFormatDto productFormatDto = BeanUtil.mapToBean(m,ProductFormatDto.class,true);
//            List<String> stringList = productFormatDto.getDetail().values()
//                    .stream()
//                    .collect(Collectors.toList());
            List<String> stringList = new ArrayList<>(productFormatDto.getDetail().values());
            Collections.sort(stringList);

            OrangeStoreProductAttrValue orangeStoreProductAttrValue = OrangeStoreProductAttrValue.builder()
                    .productId(productId)
                    .sku(StrUtil.join(",",stringList))
                    .price(BigDecimal.valueOf(productFormatDto.getPrice()))
                    .cost(BigDecimal.valueOf(productFormatDto.getCost()))
                    .otPrice(BigDecimal.valueOf(productFormatDto.getOtPrice()))
                    .vipPrice(productFormatDto.getVipPrice())
                    .unique(IdUtil.simpleUUID())
                    .image(productFormatDto.getPic())
                    .barCode(productFormatDto.getBarCode())
                    .weight(BigDecimal.valueOf(productFormatDto.getWeight()))
                    .volume(BigDecimal.valueOf(productFormatDto.getVolume()))
                    .brokerage(BigDecimal.valueOf(productFormatDto.getBrokerage()))
                    .brokerageTwo(BigDecimal.valueOf(productFormatDto.getBrokerageTwo()))
                    .stock(productFormatDto.getStock())
                    .build();


            valueGroup.add(orangeStoreProductAttrValue);
        }

        if(attrGroup.isEmpty() || valueGroup.isEmpty()){
            throw new BusinessException("请设置至少一个属性!");
        }

        //清理属性
        this.clearProductAttr(productId);

        //批量添加
        this.saveBatch(attrGroup);
        storeProductAttrValueService.saveBatch(valueGroup);

        Map<String,Object> map = new LinkedHashMap<>();
        map.put("attr",items);
        map.put("value",attrs);

        storeProductAttrResultService.insertOrangeStoreProductAttrResult(map,productId);
    }

    /**
     * 删除OrangeStoreProductAttrValue表的属性
     * @param productId 商品id
     */
    private void clearProductAttr(Long productId) {
        if(ObjectUtil.isNull(productId)) {
            throw new OrangeException("产品不存在");
        }

        orangeStoreProductAttrMapper.delete(Wrappers.<OrangeStoreProductAttr>lambdaQuery()
                .eq(OrangeStoreProductAttr::getProductId,productId));
        orangeStoreProductAttrValueMapper.delete(Wrappers.<OrangeStoreProductAttrValue>lambdaQuery()
                .eq(OrangeStoreProductAttrValue::getProductId,productId));

    }


    /**
     * 增加库存减去销量
     * @param num 数量
     * @param productId 商品id
     * @param unique sku唯一值
     */
    @Override
    public void incProductAttrStock(Integer num, Long productId, String unique) {
        orangeStoreProductAttrValueMapper.incStockDecSales(num,productId,unique);
    }

    /**
     * 减少库存增加销量
     * @param num 数量
     * @param productId 商品id
     * @param unique sku唯一值
     */
    @Override
    public void decProductAttrStock(int num, Long productId, String unique) {
        int res = orangeStoreProductAttrValueMapper.decStockIncSales(num,productId,unique);
        if(res == 0) {
            throw new OrangeException("商品库存不足");
        }
    }



    /**
     * 更加sku 唯一值获取sku对象
     * @param unique 唯一值
     * @return OrangeStoreProductAttrValue
     */
    @Override
    public OrangeStoreProductAttrValue uniqueByAttrInfo(String unique) {
        return orangeStoreProductAttrValueMapper.selectOne(Wrappers.<OrangeStoreProductAttrValue>lambdaQuery()
                .eq(OrangeStoreProductAttrValue::getUnique,unique));
    }


    /**
     * 获取商品sku属性
     * @param productId 商品id
     * @return map
     */
    @Override
    public Map<String, Object> getProductAttrDetail(long productId) {

        List<OrangeStoreProductAttr>  storeProductAttrs = orangeStoreProductAttrMapper
                .selectList(Wrappers.<OrangeStoreProductAttr>lambdaQuery()
                        .eq(OrangeStoreProductAttr::getProductId,productId)
                        .orderByAsc(OrangeStoreProductAttr::getAttrValues));

        List<OrangeStoreProductAttrValue>  productAttrValues = storeProductAttrValueService
                .list(Wrappers.<OrangeStoreProductAttrValue>lambdaQuery()
                        .eq(OrangeStoreProductAttrValue::getProductId,productId));


        Map<String, OrangeStoreProductAttrValue> map = productAttrValues.stream()
                .collect(Collectors.toMap(OrangeStoreProductAttrValue::getSku, p -> p));

        List<OrangeStoreProductAttrQueryVo> orangeStoreProductAttrQueryVoList = new ArrayList<>();

        for (OrangeStoreProductAttr attr : storeProductAttrs) {
            List<String> stringList = Arrays.asList(attr.getAttrValues().split(","));
            List<AttrValueDto> attrValueDTOS = new ArrayList<>();
            for (String str : stringList) {
                AttrValueDto attrValueDTO = new AttrValueDto();
                attrValueDTO.setAttr(str);
                attrValueDTOS.add(attrValueDTO);
            }
            OrangeStoreProductAttrQueryVo attrQueryVo = generator.convert(attr, OrangeStoreProductAttrQueryVo.class);
            attrQueryVo.setAttrValue(attrValueDTOS);
            attrQueryVo.setAttrValueArr(stringList);

            orangeStoreProductAttrQueryVoList.add(attrQueryVo);
        }

        Map<String, Object> returnMap = new LinkedHashMap<>(2);
        returnMap.put("productAttr", orangeStoreProductAttrQueryVoList);
        returnMap.put("productValue",map);

        return returnMap;
    }

}
